import os
import stat
import paramiko
import logging

class SFTPSync:
    def __init__(self, host, port, username, password):
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.ssh = None
        self.sftp = None
        self.logger = logging.getLogger(__name__)

    def connect(self):
        """建立SFTP连接"""
        self.ssh = paramiko.SSHClient()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.ssh.connect(
            hostname=self.host,
            port=self.port,
            username=self.username,
            password=self.password
        )
        self.sftp = self.ssh.open_sftp()
        return self.sftp

    def clear_remote_directory(self, remote_dir):
        """清空远程目录中的所有文件"""
        if not self.sftp:
            raise Exception("SFTP连接未建立，请先调用connect()")

        try:
            # 获取远程目录中的所有条目
            for entry in self.sftp.listdir_attr(remote_dir):
                # 构建完整路径
                entry_path = f"{remote_dir}{entry.filename}"
                # 判断是否为文件(不是目录)
                if not stat.S_ISDIR(entry.st_mode):
                    # 删除文件
                    self.sftp.remove(entry_path)
                    logging.info(f"已删除远程文件: {entry_path}")
        except FileNotFoundError:
            logging.warning(f"远程目录不存在，将创建: {remote_dir}")
            self.sftp.mkdir(remote_dir)
        except Exception as e:
            logging.error(f"清空远程目录失败: {str(e)}", exc_info=True)
            raise

    def upload_file(self, local_path, remote_dir):
        """上传本地文件到远程目录"""
        if not self.sftp:
            raise Exception("SFTP连接未建立，请先调用connect()")

        # 获取本地文件名
        filename = os.path.basename(local_path)
        remote_path = f"{remote_dir}{filename}"

        try:
            self.sftp.put(local_path, remote_path)
            logging.info(f"文件已上传至: {remote_path}")
            return True
        except PermissionError:
            # 权限不足时尝试上传到临时位置
            remote_path = f"{remote_dir}tmp_{filename}"
            self.sftp.put(local_path, remote_path)
            logging.warning(f"权限受限，文件已上传至临时位置: {remote_path}")
            return True
        except Exception as e:
            logging.error(f"文件上传失败: {str(e)}", exc_info=True)
            raise

    def close(self):
        """关闭SFTP和SSH连接"""
        if self.sftp:
            self.sftp.close()
        if self.ssh:
            self.ssh.close()